using System;
using Prologis.Logging;
using Prologis.ShifterNT.FileHandler;


namespace Prologis.ShifterNT
{


    //public abstract class AppenderSkeleton : IAppender
    public class AppenderSkeleton : IAppender
    {

        Logger logger = new Logger("Prologis.Shifter");


        public AppenderSkeleton()
        {
        }

        public IFileMoveHandler FileMoveHandler { get; set; }


        int logStep = 100;
        public int LogStep
        {
            get { return logStep; }
            set { logStep = value; }
        }

        DataSourceSkeleton dataSource;
        //virtual public DataSourceSkeleton DataSource
        public DataSourceSkeleton DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }


        IDataSink dataSink;
        //virtual public IDataSink DataSink
        public IDataSink DataSink
        {
            get { return dataSink; }
            set { dataSink = value; }
        }

        public bool Execute()
        {

            try
            {

                dataSource.Active = true;
                dataSink.Active = true;
                int countRecords = dataSource.Count;
                int counterSuccess = 0;
                int counterErrors = 0;

                try
                {

                    DateTime start = DateTime.Now;
                    logger.Info("Import start.");
                    
                    foreach (FieldList fieldList in dataSource)
                    {
                        counterSuccess++;
                        if ((counterSuccess + dataSource.Filtered) % logStep == 0)
                        {
                            logger.Info(String.Format("{0} / {1} Filtered: {2} Failed: {3}", counterSuccess + dataSource.Filtered, countRecords, dataSource.Filtered, counterErrors));
                        }
                        try
                        {
                            dataSink.Take(fieldList);
                        }
                        catch (Exception e)
                        {
                            counterErrors++;
                            logger.Error(String.Format("{0} / {1} Filtered: {2} Failed: {3}", counterSuccess + dataSource.Filtered, countRecords, dataSource.Filtered, counterErrors) + " " + e.Message);
                        }
                    }
                    logger.Info(String.Format("Import completed: {0} / {1} Filtered: {2} Failed: {3} Time=[{4}]", counterSuccess + dataSource.Filtered, countRecords, dataSource.Filtered, counterErrors, (DateTime.Now - start).ToString()));

                }
                finally
                {
                    dataSource.Active = false;
                    dataSink.Active = false;
                }

                bool success = counterErrors == 0;
         
                if (this.DataSource is IFileSource && FileMoveHandler != null)
                {
                    var file = ((IFileSource)this.DataSource).File;
                    var fileMoveType = success ? FileMoveType.ToImported : FileMoveType.ToError;
                    this.FileMoveHandler.Run(file, fileMoveType);
                }

                return success;

            }
            catch (Exception e)
            {
                logger.Exception(e);
                throw new Exception("", e);
            }

        }
    }
}
